package com.aysafety.eventmodel.service.gas.impl;

import com.aysafety.eventmodel.common.DateUtils;
import com.aysafety.eventmodel.dao.GasDao;
import com.aysafety.eventmodel.dao.TreeDao;
import com.aysafety.eventmodel.dao.WindsDao;
import com.aysafety.eventmodel.service.gas.GasService;
import com.safety.algorithm.eigenvalue.EigenvalueAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @program: iotDataPlatform
 * @description: 瓦斯
 * @author: ChengQi
 * @create: 2019-02-14 15:28
 **/
@Service public class GasServiceImpl implements GasService {

    @Autowired TreeDao treeDao;
    @Autowired WindsDao windsDao;
    @Autowired GasDao gasDao;

    // 删除ArrayList中重复元素，保持顺序
    public static List<Map<String, Object>> removeDuplicateWithOrder(List<Map<String, Object>> list) {
        Set<Map<String, Object>> set = new HashSet();
        List<Map<String, Object>> newList = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = new HashMap<String, Object>(2);
            map.put("entId", list.get(i).get("entId"));
            map.put("deviceId", list.get(i).get("deviceId"));
            if (set.add(map)) {
                newList.add(map);
            }
        }
        return newList;
    }

    @Async("asyncServiceExecutor") @Override public void gasWarning(String currentTime) throws Throwable {
        /**
         *  1.获取矿区名称、工作面、m值、Δt值
         *  2.从Hbase中抓取【t-m,t】时间段的电磁强度数据,并计算出平均值，带入n小时偏差值计算
         *  3.从Hbase中抓取【t-m-Δt,t-Δt】时间段的电磁强度数据,并计算出平均值
         *  4.计算预警指标
         *  5.放入hbase中，同时放入RabbitMQ中等待消费
         */
        //m值
        int m = Integer.parseInt("3");
        //Δt值
        int dt = Integer.parseInt("30");
        Map<String, Object> treeMap = new HashMap<String, Object>(1);
        treeMap.put("type", "\'" + "Gas" + "\'");
        List<Map<String, Object>> tree = removeDuplicateWithOrder(treeDao.queryTreeData(treeMap));
        treeMap.put("type", "\'" + "Winds" + "\'");
        List<Map<String, Object>> windstree = removeDuplicateWithOrder(treeDao.queryTreeData(treeMap));
        //2.从Hbase中抓取【t-m,t】时间段的电磁强度数据,[2018-12-18 14:54:00,2018-12-18 14:57:59]
        //当前时间
        String endTime = currentTime.substring(0, 17) + "59";
        //当前时间往前m分钟
        String startTime = DateUtils.getBeforeMinuteDate(-m, currentTime).substring(0, 17) + "00";
        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();

        List<Map<String, Object>> rearWindList = new ArrayList<Map<String, Object>>();
        //查询实时风速
        for (Map<String, Object> map : windstree) {
            String entId = map.get("entId").toString();
            String deviceId = map.get("deviceId").toString();
            Map<String, Object> parram = new HashMap<String, Object>();
            parram.put("tableId", entId + "." + "WINDSREALTIME");
            parram.put("deviceId", "\'" + deviceId + "\'");
            parram.put("startTime", startTimeTimestamp);
            parram.put("endTime", endTimeTimestamp);
            List<Map<String, Object>> windsResult = windsDao.queryRealTimeByWinds(parram);
            rearWindList.addAll(windsResult);
        }

        for (Map<String, Object> map : tree) {
            String entId = map.get("entId").toString();
            String deviceId = map.get("deviceId").toString();
            Map<String, Object> parram = new HashMap<String, Object>();
            parram.put("tableId", entId + "." + "GASREALTIME");
            parram.put("entId", "\'" + entId + "\'");
            parram.put("deviceId", "\'" + deviceId + "\'");
            parram.put("startTime", startTimeTimestamp);
            parram.put("endTime", endTimeTimestamp );
            List<Map<String, Object>> rearList = gasDao.queryRealTimeByGas(parram);
            if (rearList.size() > 0) {
                double avgRear = Double.parseDouble(rearList.get(rearList.size() - 1).get("monitoringValue") + "");
                double windRear =
                    Double.parseDouble(rearWindList.get(rearWindList.size() - 1).get("monitoringValue") + "");
                double avgFront = EigenvalueAlgorithm.average(rearList, "monitoringValue");
                //4.计算预警指标
                double gasWarningIndicator = EigenvalueAlgorithm.warnings(avgRear, avgFront, dt);

                //绝对瓦斯涌出量 Q
                double gasAbsEmission = EigenvalueAlgorithm.gasAbsEmission(avgRear, windRear, 1);

                //取绝对瓦斯涌出量平均值
                parram.put("tableId", entId + "." + "CalGas");
                List<Map<String, Object>> gasEmissionList = gasDao.queryGasAbsEmissionList(parram);
                BigDecimal all = BigDecimal.valueOf(0d);
                for (Map<String, Object> tempMap : gasEmissionList) {
                    double gasEmissionTemp = tempMap.get("gasAbsEmission") == null ?
                        -1 :
                        Double.parseDouble(tempMap.get("gasAbsEmission").toString());
                    all = BigDecimal.valueOf(gasEmissionTemp).add(all);
                }
                int size = gasEmissionList.size();
                double gasAbsEmissionAvg = size == 0 ? 0 : all.doubleValue() / size;
                //瓦斯涌出变化率 I
                double gasDivide = EigenvalueAlgorithm.divide(gasAbsEmission, gasAbsEmissionAvg, -1);

                Map<String, Object> param = new HashMap<String, Object>();
                param.put("tableId", entId + "." + "CALGAS");
                param.put("pk", "\'" + DateUtils.fomatDateTime(currentTime.substring(0, 17) + "00").getTime()+ deviceId + "\'");
                param.put("entId", "\'" + entId + "\'");
                param.put("deviceId", "\'" + deviceId + "\'");
                param.put("calType", 1);
                param.put("gasWarningIndicator", gasWarningIndicator);
                param.put("gasAbsEmission", gasAbsEmission);
                param.put("gasDivide", gasDivide);
                param.put("hoursDeviation", -1);
                param.put("flag", -1);
                param.put("datetime", DateUtils.fomatDateTime(currentTime.substring(0, 17) + "00").getTime());
                param.put("dt", dt);
                param.put("m", m);
                param.put("n", 0);
                gasDao.saveCal(param);
            }
        }

    }

    @Override public void dailyComprehensiveWarning(String currentTime) throws Throwable {

    }
}
